import 'dart:async';
import 'dart:io';
import 'dart:math';

import 'package:dlna_dart/dlna.dart';

import 'package:flutter/material.dart';
import 'package:network_info_plus/network_info_plus.dart';
import 'package:screen_brightness/screen_brightness.dart';
import 'package:video_player/video_player.dart';
import 'package:flutter/services.dart';
import 'package:volume_controller/volume_controller.dart';
import 'package:eshi/app/CommonFunctions.dart';

/// 2025-08-23 04:34:46 豆包给的代码看看效果怎么样 
class VideoPlayBox extends StatefulWidget {
  final String videoUrl;
  final bool isAsset;
  final _VideoPlayBoxState? fullState;
  const VideoPlayBox({
    super.key,
    required this.videoUrl,
    this.isAsset = false,
    this.fullState,
  });

  @override
  State<VideoPlayBox> createState() => _VideoPlayBoxState();
}

class _VideoPlayBoxState extends State<VideoPlayBox> with SingleTickerProviderStateMixin {
  late VideoPlayerController _controller;
  late AnimationController _animationController;
  bool _isPlaying = false;
  bool _isFullScreen = false;
  bool _showControls = true;
  int _isControlLock = 0;      //防误触 0未开启 1 开启显示 2 开启隐藏 
  //bool _isCanAudioPlay = false;      //后台音频播放 
  bool _isScreenLandscape=true;     //横屏
  late Duration duration;           //时长
  double _volume = 1.0;       //当前音量
  double _brightness = 1.0;   //当前亮度
  double _playbackSpeed = 1.0; //当前倍速
  final List<double> _playbackSpeeds = [0.2,0.5, 0.75, 1.0, 1.25, 1.5, 2.0,3.0,8.0,16.0,32.0];
  
  // 手势相关
  bool _isDragging = false;
  Offset _startDragOffset = Offset.zero;
  bool _isAdjustingBrightness = false; //亮度
  bool _isAdjustingVolume = false; //音量
  bool _isAdjustingSeek = false;   //进度 
  bool _isPressing = false;        //长按
  double _startBrightness = 1.0;
  double _startVolume = 1.0;
  int _startSeek=0;
  String get videoName {
    return widget.videoUrl.split("/").last.split(".").first;
  }
  @override
  void initState() {
    super.initState();
    if(widget.fullState !=null){
      copyWidth(widget.fullState!);
      return; 
    } 
    // 初始化视频控制器
    _controller =// widget.videoController??
        (widget.isAsset 
        ? VideoPlayerController.asset(widget.videoUrl)
        : VideoPlayerController.networkUrl(Uri.parse(widget.videoUrl))
        );

    // 初始化动画控制器（用于控制控件淡入淡出）
    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 300),
    );
    // 初始化视频
    _initializeVideo();
  }
  void copyWidth(_VideoPlayBoxState self){
    _controller = self._controller;
    _isPlaying = self._isPlaying;
    _isFullScreen = self._isFullScreen;
    _animationController = self._animationController;
    duration = self.duration;
    _playbackSpeed = self._playbackSpeed;
  }

  @override
  void dispose() {
   if(widget.fullState==null) {
    _controller.dispose();
    _animationController.dispose();
   }
    super.dispose();
  }

  // 初始化视频
  Future<void> _initializeVideo() async {
    await _controller.initialize();    
    try{
      _volume = await VolumeController().getVolume();
      _brightness =  await ScreenBrightness().current;
    } catch (e) {
      print("获取亮度异常：$e");
    }
    await _controller.setVolume(_volume);
    _controller.addListener((){// 视频监听
      _videoListener(_controller.value.position);
    });
    setState(() {
      duration = _controller.value.duration;  
    });
  }

  // 视频监听
  void _videoListener(Duration position) {
      if (duration.inMilliseconds > 0 && position.inMilliseconds >= duration.inMilliseconds - 100) { // 允许100ms误差
        onVideoCompleted(); // 触发播放结束回调
      }
      setState(() {
        
      });
  }

  void onVideoCompleted(){
    _controller.pause();
    _controller.seekTo(Duration(seconds: 0));
  }
  // 切换播放/暂停
  void _togglePlayPause() {
    setState(() {
      if (_controller.value.isPlaying) {
        _controller.pause();
        _isPlaying = false;
      } else {
        _controller.play();
        _isPlaying = true;
        _hideControls(2000);
      }
    });
  }

  // 快进/后退
  void _seek(Duration duration) {
    final newPosition = _controller.value.position + duration;
    _controller.seekTo(newPosition);
  }

  void refrashScreenOrientation(){
      if(_isScreenLandscape){
        SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky);
        SystemChrome.setPreferredOrientations([
          DeviceOrientation.landscapeLeft,
          DeviceOrientation.landscapeRight,
        ]);
      }else{
        SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: SystemUiOverlay.values);
        SystemChrome.setPreferredOrientations([
          DeviceOrientation.portraitUp,
        ]);
      }
  }
  // 切换全屏
  void _toggleFullScreen() async{
    _isFullScreen = !_isFullScreen;  
    if (_isFullScreen) {
      _isScreenLandscape = true;
      refrashScreenOrientation();
      await Navigator.push(
        context,
        MaterialPageRoute(
          builder: (context) => Scaffold(
            // appBar: AppBar(title: Text(title)),
            body: VideoPlayBox(videoUrl: widget.videoUrl,fullState: this)
          ),
        ),
      );
      setState(() {
        _isFullScreen = false;  
        _showControls = true;
      });
      _isFullScreen = false;
    }else if(widget.fullState!=null){
      Navigator.pop(context); 
      return;
    }

     _isScreenLandscape = false;
    refrashScreenOrientation();
  }

  // 设置播放速度
  void _setPlaybackSpeed(double speed) {
    setState(() {
      _playbackSpeed = speed;
      _controller.setPlaybackSpeed(speed);
    });
  }

  // 隐藏控制栏
  void _hideControls([int timeOut=0]) {
    // if (_controller.value.isPlaying) {
    //   _animationController.forward().then((_) {
    //     if (mounted) {
    //       setState(() => _showControls = false);
    //     }
    //   });
    // }
    if(timeOut==0){
      setState(() => _showControls = false);
    }else{
      stringRun(timeOut,()=>setState(() {
        _showControls = false;
      }));
    }
  }

  // 格式化时长
  String _formatDuration(Duration duration) {
    String twoDigits(int n) => n.toString().padLeft(2, '0');
    final hours = twoDigits(duration.inHours);
    final minutes = twoDigits(duration.inMinutes.remainder(60));
    final seconds = twoDigits(duration.inSeconds.remainder(60));
    
    return hours == '00' 
        ? "$minutes:$seconds" 
        : "$hours:$minutes:$seconds";
  }

  // 处理滑动手势
  void _handleDragStart(DragStartDetails details,[bool isVertical = true]) {
    if(_isControlLock > 0) return;
    _isDragging = true;
    _startDragOffset = details.globalPosition;
    _startBrightness = _brightness;
    _startVolume = _volume;
    print("drag start(${isVertical ? "上下":"左右"})");
    setState(() {
      if(isVertical){
          // 判断触摸位置在左侧还是右侧
          final screenWidth = MediaQuery.of(context).size.width;
          _isAdjustingBrightness = details.globalPosition.dx < screenWidth / 2;
          _isAdjustingVolume = !_isAdjustingBrightness;
      }else if(_isPlaying){
        _isAdjustingSeek = true;
        _controller.position.then((v){
          seekTo = v;
          _startSeek = v!.inSeconds;
        });
      }
    });
  }
  Offset tmpLastPosition = Offset(0,0);
  Duration? seekTo;
  //小窗显示与拖动相关 
  final bool _isPipMode=false;
  Offset _pipPosition = const Offset(20, 100); // 小窗初始位置
  final double _pipWidth = 200; // 小窗宽度
  Offset _offsetDelta = Offset.zero;  //拖动相关变量
    // 计算小窗高度（根据宽高比）
  double get _pipHeight {
    return _pipWidth / _controller.value.aspectRatio;
  }
 void _handlePipMove(DragUpdateDetails details) {
    if (!_isDragging) return;

    // 计算新位置（限制在屏幕内）
    final RenderBox renderBox = context.findRenderObject() as RenderBox;
    final screenSize = renderBox.size;

    setState(() {
      _pipPosition = Offset(
        // 限制X轴在屏幕内
        details.globalPosition.dx - _offsetDelta.dx.clamp(
          0,
          screenSize.width - _pipWidth,
        ),
        // 限制Y轴在屏幕内
        details.globalPosition.dy - _offsetDelta.dy.clamp(
          0,
          screenSize.height - (_pipWidth / _controller.value.aspectRatio),
        ),
      );
    });
  }
  
  // 处理滑动更新
  void _handleDragUpdate(DragUpdateDetails details) {
    if (!_isDragging) {
      //长按之后滑动 上下是倍速 左右是快进或快退 
       final dy = details.globalPosition.dy-tmpLastPosition.dy;
       final dx = details.globalPosition.dx-tmpLastPosition.dx;
       final dMax = max(dy.abs(),dx.abs());
       print("drap:$dMax");
       if(dMax<2) return;
       //横向还是纵向 
       if(dx.abs() == dMax){
          _seek(Duration(seconds: (5 * _playbackSpeed * dx).toInt() ));
       }else{
          var index = _playbackSpeeds.indexOf(_playbackSpeed);
          final n = 2;
          index = min(_playbackSpeeds.length-1,max(0,(dy/n).toInt()+index));
          setState(() {
            _playbackSpeed = _playbackSpeeds[index];
            print("drap: $_playbackSpeed");
          });
       }
       tmpLastPosition = details.globalPosition;
       return;
    }
    
    final deltaY = _startDragOffset.dy - details.globalPosition.dy;
    final sensitivity = 0.005; // 灵敏度
    
    if (_isAdjustingBrightness) {
      // 调整亮度
      setState(() {
        _brightness = (_startBrightness + deltaY * sensitivity).clamp(0.0, 1.0);
        SystemChannels.platform.invokeMethod('SystemChrome.setSystemBrightness', _brightness);
      });
    } else if (_isAdjustingVolume) {
      // 调整音量
      setState(() {
        _volume = (_startVolume + deltaY * sensitivity).clamp(0.0, 1.0);
        _controller.setVolume(_volume);
      });
    }else if(_isAdjustingSeek){
      final deltaX = details.globalPosition.dx - _startDragOffset.dx;
      final seekS = min(duration.inSeconds, max(0,(deltaX).toInt()+ _startSeek)); 
      seekTo = Duration(seconds: seekS );
    }
    
    print("dragging...");
  }

  // 处理滑动结束
  void _handleDragEnd(DragEndDetails details) {
    if(seekTo!=null){
        _controller.seekTo(seekTo!);
    }
    setState(() {
      _isDragging = false;
      _isAdjustingBrightness = false;
      _isAdjustingVolume = false;   
      tmpLastPosition = Offset(0,0);
      seekTo = null;
      _startSeek = 0;
    });
  }
  
  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    
    return Scaffold(
      backgroundColor: Colors.black,
      body: Stack(children: [
         if(_isPipMode)
              Positioned(
                  left: _pipPosition.dx,
                  top: _pipPosition.dy,
                  width: _pipWidth,
                  height: _pipHeight,
                  child: GestureDetector(
                    onPanStart: (DragStartDetails details) =>  _offsetDelta = Offset(
                      details.localPosition.dx,
                      details.localPosition.dy,
                    ),
                    onPanUpdate: _handlePipMove,
                    child: Material(
                      elevation: 4, // 阴影效果，突出小窗
                      borderRadius: BorderRadius.circular(8),
                      child: _buildPlayer(Size(_pipWidth,_pipHeight)),
                    ),
                  ),
                ),
         if(!_isPipMode)
          _buildPlayer(size),
      ])
    );
  }

  // 构建播放器
  Widget _buildPlayer(Size size) {
    if (!_controller.value.isInitialized) {
      return const Center(child: CircularProgressIndicator());
    }

    return GestureDetector(
      onLongPressStart: (d) {
        if(_isControlLock==0 && _isPlaying){
           _isPressing=true;
           _setPlaybackSpeed(5.0);
        }
      },
      onLongPressEnd:(d){
        _isPressing = false;
        _setPlaybackSpeed(1.0);
      },
      onHorizontalDragStart: (details) => _handleDragStart(details,false),
      onHorizontalDragUpdate: (details) => _handleDragUpdate(details),
      onHorizontalDragEnd: (details) => _handleDragEnd(details),
      onVerticalDragStart: (details) => _handleDragStart(details),
      onVerticalDragUpdate: (details) => _handleDragUpdate(details),
      onVerticalDragEnd: (details) => _handleDragEnd(details),
      onTapUp: (e) {
        if(_isControlLock > 0){
          setState(() {
             _isControlLock ==1 ? _isControlLock =2 : _isControlLock =1;  
                 //锁定框延迟3s之后关闭 
            if(_isControlLock==1){
              setTimeout(() => setState(() {
                  _isControlLock = 2;
                }),3000);     
            }
          });
          return;
        }
       if( _isAdjustingBrightness || _isAdjustingVolume || _isPressing) return;
       setState(() {
         _showControls = !_showControls; 
        if(_showControls){
            _hideControls(5000);
        }  
       });

      },
      child: Stack(
        children: [
          // 视频播放器
          Center(
            child: AspectRatio(
              aspectRatio: _controller.value.aspectRatio,
              child: VideoPlayer(_controller),
            ),
          ),
         
          // 加载指示器
          if (_controller.value.isBuffering)
            const Center(child: CircularProgressIndicator()),
          
          // 亮度/音量调节指示器
          if (_isAdjustingBrightness)
            _buildAdjustmentIndicator("亮度", _brightness, Icons.brightness_7),
          
          if (_isAdjustingVolume)
            _buildAdjustmentIndicator("音量", _volume, _volume > 0 ? Icons.volume_up : Icons.volume_off),
          
          // 控制栏
          if (_showControls)
            AnimatedOpacity(
              opacity: _showControls ? 1.0 : 0.0,
              duration: const Duration(milliseconds: 300),
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  // 顶部控制栏
                  _buildTopControls(),
                  
                  // 底部控制栏
                  _buildBottomControls(),
                ],
              ),
            ),
          //长按倍速显示的时候倍速信息 
          if(!_showControls &&  _playbackSpeed!=1.0)
            Align(
              alignment: AlignmentGeometry.topRight,
              child : Wrap(
                spacing: 8.0,
                children: [
                  if(_isPressing)
                   Text(
                      "${_formatDuration(_controller.value.position)} / ${_formatDuration(_controller.value.duration)}",
                     style: const TextStyle(color: Colors.white),
                   ),
                  Text("${_playbackSpeed}x",style:TextStyle(color: Colors.white)),
                  SizedBox(width: 10,)
                ]
              )
            ),
          //滑动跳转 
          if(seekTo!=null)
            Center(child: Container(
              padding: const EdgeInsets.all(12),
              decoration: BoxDecoration(
                color: Colors.black54,
                borderRadius: BorderRadius.circular(8),
              ),
              child:Text(
              "${_formatDuration(seekTo!)} / ${_formatDuration(_controller.value.duration)}",
              style: const TextStyle(color: Colors.white),
            ))),
          //锁定按钮 
          if(_isControlLock ==1)
              Align(
                alignment: AlignmentGeometry.topRight,
                child: Wrap(
                  children: [
                    IconButton(
                      icon: Icon(Icons.lock ,
                        color: Colors.white,
                      ),
                      onPressed: () => setState(() {
                        _isControlLock = 0;
                        _showControls = true;
                        
                      }),
                    ),
                    SizedBox(width: 16) 
                  ],
                ),
            )
        ],
      ),
    );
  }

  // 构建调节指示器
  Widget _buildAdjustmentIndicator(String label, double value, IconData icon) {
    return Center(child:  Container(
        padding: const EdgeInsets.all(12),
        decoration: BoxDecoration(
          color: Colors.black54,
          borderRadius: BorderRadius.circular(8),
        ),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Icon(icon, color: Colors.white, size: 32),
            const SizedBox(height: 8),
            Text(
              "$label: ${(value * 100).round()}%",
              style: const TextStyle(color: Colors.white, fontSize: 16),
            ),
            const SizedBox(height: 8),
            SizedBox(
              width: 100,
              child: LinearProgressIndicator(
                value: value,
                backgroundColor: Colors.white30,
                valueColor: const AlwaysStoppedAnimation<Color>(Colors.white),
              ),
            ),
          ],
        ),
      ));
  }

  // 构建顶部控制栏
  Widget _buildTopControls() {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 2),
      // color: Colors.black54,
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          Text(videoName,style:TextStyle(color: Colors.white)),
          Row(children: [
            if(_isFullScreen)
              IconButton(
              icon: Icon( Icons.screen_rotation,
                // _isScreenLandscape ? 
                //   Icons.screen_lock_landscape
                //   : Icons.screen_lock_portrait,
                color: Colors.white,
              ),
              onPressed: () => setState(() {
                _isScreenLandscape = !_isScreenLandscape;
                refrashScreenOrientation();
              })),
            PopupMenuButton<double>(
                icon: _playbackSpeed==1.0? const Icon(Icons.speed, color: Colors.white) : Text("${_playbackSpeed}x",style:TextStyle(color: Colors.white)),
                itemBuilder: (context) => _playbackSpeeds.map((speed) {
                  return PopupMenuItem(
                    value: speed,
                    textStyle:_playbackSpeed == speed? TextStyle(color: Colors.blueAccent) : null,
                    child: Text("${speed}x"),
                  );
                }).toList(),
                onSelected: _setPlaybackSpeed,
              ),
            if(_isFullScreen)
             IconButton(
              icon: Icon(Icons.lock_open,
                color: Colors.white,
              ),
              onPressed: () => setState(() {
                      _showControls = false;
                      _isControlLock = 1;
                      setTimeout(() => setState(() {
                        _isControlLock = 2;
                      }),3000);     
              }),
            ), 
          ])
        ],
      ),
    );
  }
  final GlobalKey<PopupMenuButtonState> _popupKey = GlobalKey();

  // 构建底部控制栏
  Widget _buildBottomControls() {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 0),
      // color: Colors.black54,
      child: Column(
        children: [
          // 进度条
          _buildProgressBar(),
          
          // const SizedBox(height: 8),
          
          // 控制按钮
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              // 时间显示
              Text(
                "${_formatDuration(_controller.value.position)} / ${_formatDuration(_controller.value.duration)}",
                style: const TextStyle(color: Colors.white),
              ),
              
              // 控制按钮组
              Row(
                children: [
                  // IconButton(
                  //   icon: const Icon(Icons.replay_10, color: Colors.white),
                  //   onPressed: () => _seek(const Duration(seconds: -10)),
                  // ),
                  
                  IconButton(
                    icon: Icon(
                      _controller.value.isPlaying 
                          ? Icons.pause 
                          : Icons.play_arrow,
                      color: Colors.white,
                      size: 28,
                    ),
                    onPressed: _togglePlayPause,
                  ),
                  
                  // IconButton(
                  //   icon: const Icon(Icons.forward_10, color: Colors.white),
                  //   onPressed: () => _seek(const Duration(seconds: 10)),
                  // ),

                  
                  // if(_isFullScreen)
                  // IconButton(
                  //   icon: Icon(  Icons.audiotrack,
                  //     color: _isCanAudioPlay ? Colors.white :Colors.grey,
                  //   ),
                  //   onPressed: () => setState(() {
                  //     _isCanAudioPlay = !_isCanAudioPlay;
                  //   }) 
                  // ), 
                  (_devices.isEmpty)
                  ? IconButton(
                    icon: Icon(Icons.airplay,
                      color: _selectedDevice==null ? Colors.white :Colors.blue,
                    ),
                    onPressed: () {
                      if(!dlnaDeviceLoading) airPlay(_selectedDevice);
                    },
                    // onLongPress: () => setState(() {
                    //   _selectedDevice = null;
                    //    airPlay(null);
                    // }),
                  )
                  :PopupMenuButton<DlnaDevice>(
                    key:_popupKey,
                    icon: Icon(Icons.airplay, color: Colors.blue,),
                    itemBuilder: (context) => _devices.map((dev) {
                      return PopupMenuItem(
                        value: dev,
                        textStyle:dev == _selectedDevice? TextStyle(color: Colors.blueAccent) : null,
                        child: Text("${dev.name}(${dev.host})"),
                      );
                    }).toList(),
                    onSelected: (dev) => airPlay(dev),
                  ),
                  // IconButton(
                  //   icon: Icon( Icons.fit_screen_outlined,
                  //     color: Colors.white,
                  //   ),
                  //   onPressed: () => setState(() {
                  //     _isPipMode = true;
                  //   }),
                  // ), 
                  IconButton(
                    icon: Icon(
                      _isFullScreen 
                          ? Icons.fullscreen_exit 
                          : Icons.fullscreen,
                      color: Colors.white,
                    ),
                    onPressed: _toggleFullScreen,
                  ),
                ],
              ),
            ],
          ),
        ],
      ),
    );
  }

  final FlutterDlna _flutterDlna = FlutterDlna();
  List<DlnaDevice> _devices = FlutterDlna.cacheDevices; // 发现的投屏设备
  DlnaDevice? _selectedDevice = FlutterDlna.defaultDevice; // 选中的设备
  bool dlnaDeviceLoading = false;
  //投屏
  airPlay(DlnaDevice? device) async{
    //搜索设备
    if(device==null) {
      dlnaDeviceLoading =true;
      // 监听设备发现事件
      _flutterDlna.searchDevices((devices) {
        setState(() => _devices = devices);
        if(dlnaDeviceLoading){
          Timer(Duration(milliseconds: 500), (){
            _popupKey.currentState?.showButtonMenu();
          });
        }
        dlnaDeviceLoading = false;
      });
      
      //图标闪烁
      Timer.periodic(const Duration(seconds: 1), (t){
        setState(() {
          _selectedDevice = _selectedDevice == null? DlnaDevice() : null;
          if(_devices.isNotEmpty){
            _selectedDevice = null;
            t.cancel();  
          }
        });
      });
      return;
    }
    //连接设备
    if(_selectedDevice!=device){
      _selectedDevice = device;
      FlutterDlna.defaultDevice = _selectedDevice;
    }
    // 发送视频地址到投屏设备
    await _flutterDlna.setMedia(
      device: device,
      url: widget.videoUrl,
      title: videoName,
      type: "video/mp4",
    );
     // 开始播放
    await _flutterDlna.start();
  }
  
  
  // 构建进度条
  Widget _buildProgressBar() {
    return Slider(
      padding: EdgeInsets.all(0),
      value: _controller.value.position.inMilliseconds.toDouble(),
      min: 0.0,
      max: _controller.value.duration.inMilliseconds.toDouble(),
      activeColor: Colors.red,
      inactiveColor: Colors.white30,
      thumbColor: Colors.white,
      onChanged: (value) {
        setState(() {
          _controller.seekTo(Duration(milliseconds: value.toInt()));
        });
      },
      onChangeStart: (_) => setState(() => _isDragging = true),
      onChangeEnd: (_) {
        setState(() => _isDragging = false);
        _hideControls(2000);
      },
    );
  }
}

class DlnaDevice{
  String name="";
  String host="";
  DLNADevice? model;
  DlnaDevice({this.name="",this.host="", this.model});
  
  static List<DlnaDevice> fromDeviceList(Map<String, DLNADevice> deviceList) {
    final List<DlnaDevice> rt = [];
    deviceList.forEach((key, value) async {
      if (value.info.friendlyName.contains('Wireless')) return;
      rt.add(DlnaDevice(name:value.info.friendlyName,host:key,model:value));
    });
    return rt;
  }
}

class FlutterDlna{
  String avTransportUrl="";
  String? _videoUrl;
  
  setVideoUrl(String v) async {
    if(v.startsWith("/")){
      final file = File(v);
      _videoUrl = await LocalFileServer().start(file);
    }else{
      _videoUrl = v;
    }

    return _videoUrl != null;
  }
  String title ="";
  late DLNADevice dlnaDevice;

  Future<bool> setMedia({required DlnaDevice device, required String url, required String title, required String type}) async {
    if(! await setVideoUrl(url)){
        return false;
    }
    this.title = title;
    dlnaDevice = device.model!;
    dlnaDevice.setUrl(_videoUrl!,title:title);
    
    return true;
  }
  
  Future<void> start() async {
    await dlnaDevice.play();
  }
 static List<DlnaDevice> cacheDevices = [];
 static DlnaDevice? defaultDevice;
  void searchDevices(Null Function(dynamic devices) func) async{
    if(cacheDevices.isNotEmpty) {
        func(cacheDevices);
        return;
    } 
    final searcher = DLNAManager();
      final m = await searcher.start();
      List<DlnaDevice> devices = [];
      m.devices.stream.listen((deviceList) {
        devices = DlnaDevice.fromDeviceList(deviceList);
         func(devices);
      });
       // close the server,the closed server can be start by call searcher.start()
      Timer(Duration(seconds: 30), () {
        searcher.stop();
        cacheDevices = devices;
        print('server closed');
      });
      
  }
}

// 2. 本地 HTTP 服务器（共享本地文件）
class LocalFileServer {
  late HttpServer _server;
  final int _port = 8080; // 端口可自定义（1024-65535）
  String? _localIp; // 手机局域网 IP
  File? _sharedFile; // 当前共享的文件
  static LocalFileServer? _instance;
  LocalFileServer(){
    if(_instance!=null) _instance!.stop();
    _instance = this;
  }
  // 启动服务器并共享指定文件
  Future<String?> start(File file) async {
    try {
      _sharedFile = file;
      // 获取手机局域网 IP（关键：确保投屏设备能访问）
      _localIp = await NetworkInfo().getWifiIP();
      if (_localIp == null) return null;

      // 启动 HTTP 服务器
      _server = await HttpServer.bind(InternetAddress.anyIPv4, _port);
      print("本地服务器启动：http://$_localIp:$_port");
      final fileSize = await file.length();
      // 处理文件请求
      _server.listen((request) {

        if (request.uri.path == "/${file.urlName}" && _sharedFile != null) {
          // 返回文件内容
          request.response.headers.contentType = ContentType.parse(_getMimeType(file.path));
          request.response.headers.add("Content-Length", fileSize); // 文件总大小
          // request.response.headers.add("Accept-Ranges", "bytes"); // 支持断点续传
          request.response.statusCode = HttpStatus.ok; // 200 OK
          _sharedFile!.openRead().pipe(request.response);
          //  _sendFileWithBuffer(request, file);
        } else {
          request.response.statusCode = HttpStatus.notFound;
          request.response.close();
        }
      });

      // 返回文件的网络 URL
      return "http://$_localIp:$_port/${file.baseName}";
    } catch (e) {
      print("服务器启动失败：$e");
      return null;
    }
  }
// 核心：分块发送文件（自定义缓冲大小）
  // ignore: unused_element
  void _sendFileWithBuffer(HttpRequest request, File file) {
    // 设置响应头（MIME 类型）
    request.response.headers.contentType = ContentType.parse(_getMimeType(file.path));
    
    // 创建文件读取流（每次读取 _bufferSize 大小的块）
    final fileStream = file.openRead().transform(StreamTransformer.fromHandlers(
      handleData: (List<int> chunk, EventSink<List<int>> sink) {
        // 这里可以控制每块的发送逻辑（如限速、日志）
        print("发送块大小：${chunk.length} 字节");
        sink.add(chunk); // 将缓冲块发送到响应
      },
      handleError: (error, stackTrace, sink) {
        print("文件读取错误：$error");
        sink.addError(error);
      },
      handleDone: (sink) {
        print("文件发送完成");
        sink.close(); // 所有块发送完毕，关闭流
      },
    ));

    // 将处理后的文件流管道到响应
    fileStream.pipe(request.response).catchError((error) {
      print("发送失败：$error");
    });
  }
  // 停止服务器
  Future<void> stop() async {
    await _server.close();
    _sharedFile = null;
    print("本地服务器已停止");
  }

  // 获取文件 MIME 类型（确保设备正确解析文件）
  String _getMimeType(String path) {
    if (path.endsWith(".mp4")) return "video/mp4";
    if (path.endsWith(".mov")) return "video/quicktime";
    if (path.endsWith(".avi")) return "video/x-msvideo";
    if (path.endsWith(".mkv")) return "video/x-matroska";
    return "video/*"; // 默认视频类型
  }
}

extension on File {
  // ignore: unused_element
  String get exName => path.substring(path.lastIndexOf('.')).toLowerCase();
  String get baseName =>  path.split(Platform.pathSeparator).last;
  String get urlName =>  Uri.encodeComponent(baseName);
}